﻿using FileSynchronizationClient.Models;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;

namespace FileSynchronizationClient.Common
{
    public static class HttpBaseUrl
    {
        public const string BaseUrl = "https://syncfile.lxhxl.cn";
    }

    #region SyncPackHttpClient
    /// <summary>
    /// SyncPackHttpClient
    /// </summary>
    public class SyncPackHttpClient
    {
        private HttpclientHelper _httpClient;
        private FileSynchronizationAuthorization _authorization;
        public SyncPackHttpClient(HttpclientHelper httpClient, FileSynchronizationAuthorization authorization)
        {
            _httpClient = httpClient;
            _authorization = authorization;
        }

        /// <summary>
        /// 上传文件（带分片）
        /// </summary>
        /// <param name="publishType">发布类型</param>
        /// <param name="fileByte">上传字节块</param>
        /// <param name="fileName">文件名字</param>
        /// <param name="baseDir">Base文件夹</param>
        /// <param name="chunk">当前片（分片传）</param>
        /// <param name="chunks">总片数（分片传）</param>
        /// <param name="guid">唯一标识（分片传）</param>
        /// <returns></returns>
        public async Task UploadFile(
            int publishType,
            byte[] fileByte,
            string fileName,
            string baseDir = "",
            int chunk = 0,
            int chunks = 0,
            string guid = "")
        {
            // 创建 MultipartFormDataContent
            using var formData = new MultipartFormDataContent();

            // 读取文件内容
            using var fileContent = new ByteArrayContent(fileByte);

            // 将文件内容添加为表单数据
            formData.Add(fileContent, "file", fileName);

            formData.Add(new StringContent(chunk.ToString()), "chunk");
            formData.Add(new StringContent(chunks.ToString()), "chunks");
            formData.Add(new StringContent(guid), "guid");
            formData.Add(new StringContent(baseDir), "baseDir");

            // 发起上传请求
            await _httpClient.Post(SyncPackHttpUrl.UploadPackFile.FillType(publishType), _authorization.Authorization, formData);
        }

        /// <summary>
        /// 清空远程包文件
        /// </summary>
        /// <param name="publishType">发布类型</param>
        /// <returns></returns>
        public async Task<ReturnModel> ClearPackFile(int publishType) => await _httpClient.Post(SyncPackHttpUrl.ClearPackFile.FillType(publishType), _authorization.Authorization);

        /// <summary>
        /// 同步远程包文件
        /// </summary>
        /// <param name="publishType">发布类型</param>
        /// <returns></returns>
        public async Task<ReturnModel> SyncPackFile(int publishType) => await _httpClient.Post(SyncPackHttpUrl.SyncPackFile.FillType(publishType), _authorization.Authorization);

        /// <summary>
        /// 删除远程包文件
        /// </summary>
        /// <param name="publishType">发布类型</param>
        /// <returns></returns>
        public async Task<ReturnModel> RemovePackBak(int publishType) => await _httpClient.Post(SyncPackHttpUrl.RemovePackBak.FillType(publishType), _authorization.Authorization);
    }

    /// <summary>
    /// SyncPackHttpUrl
    /// </summary>
    public static class SyncPackHttpUrl
    {
        private const string baseUrl = $"{HttpBaseUrl.BaseUrl}/FileAsync";

        /// <summary>
        /// 清空远程包文件 Post
        /// </summary>
        public static string ClearPackFile = $"{baseUrl}/ClearPackFile/{{Type}}";

        /// <summary>
        /// 上传远程包文件 Post
        /// </summary>
        public static string UploadPackFile = $"{baseUrl}/UploadPackFile/{{Type}}";

        /// <summary>
        /// 开始同步远程包文件 Post
        /// </summary>
        public static string SyncPackFile = $"{baseUrl}/SyncPackFile/{{Type}}";

        /// <summary>
        /// 删除远程包文件备份 Post
        /// </summary>
        public static string RemovePackBak = $"{baseUrl}/RemovePackBak/{{Type}}";

        /// <summary>
        /// 填充Type
        /// </summary>
        /// <param name="url"></param>
        /// <param name="publishType"></param>
        /// <returns></returns>
        public static string FillType(this string url, int publishType) => url.Replace("{Type}", $"{publishType}");
    }
    #endregion

    #region UserHttpClient
    /// <summary>
    /// UserHttpClient
    /// </summary>
    public class UserHttpClient
    {
        private HttpclientHelper _httpClient;
        private FileSynchronizationAuthorization _authorization;
        public UserHttpClient(HttpclientHelper httpClient, FileSynchronizationAuthorization authorization)
        {
            _httpClient = httpClient;
            _authorization = authorization;
        }

        /// <summary>
        /// GetToken
        /// </summary>
        /// <param name="model">model</param>
        /// <returns></returns>
        public async Task<ReturnModel> GetToken(GetTokenRequest model)
        {
            //var url = _httpClient.GetNewUrl(UserHttpUrl.Token, "Account", model.Account, "Password", model.Password, "Type", model.Type);

            var content = new StringContent(JsonConvert.SerializeObject(model));
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            return await _httpClient.Post(UserHttpUrl.Token, content: content);
        }
    }

    /// <summary>
    /// UserHttpUrl
    /// </summary>
    public static class UserHttpUrl
    {
        private const string baseUrl = $"{HttpBaseUrl.BaseUrl}/User";

        /// <summary>
        /// 获取Token Post
        /// </summary>
        public static string Token = $"{baseUrl}/Token";
    }
    #endregion

    #region CommonHttpClient
    /// <summary>
    /// CommonHttpClient
    /// </summary>
    public class CommonHttpClient
    {
        private HttpclientHelper _httpClient;
        private FileSynchronizationAuthorization _authorization;
        public CommonHttpClient(HttpclientHelper httpClient, FileSynchronizationAuthorization authorization)
        {
            _httpClient = httpClient;
            _authorization = authorization;
        }

        /// <summary>
        /// GetPublishSetting
        /// </summary>
        /// <returns></returns>
        public async Task<ReturnModel> GetPublishSetting()
        {
            return await _httpClient.Get(CommonHttpUrl.PublishSetting);
        }
    }

    /// <summary>
    /// CommonHttpUrl
    /// </summary>
    public static class CommonHttpUrl
    {
        private const string baseUrl = $"{HttpBaseUrl.BaseUrl}/Common";

        /// <summary>
        /// 获取PublishSetting Get
        /// </summary>
        public static string PublishSetting = $"{baseUrl}/PublishSetting";
    }
    #endregion

    #region HttpclientHelper
    public class HttpclientHelper
    {
        private IHttpClientFactory _httpClientFactory;
        public HttpclientHelper(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        /// <summary>
        /// post request
        /// </summary>
        /// <param name="apiUrl"></param>
        /// <returns></returns>
        public async Task<ReturnModel> Post(string apiUrl, string authorization = "", HttpContent content = null)
        {
            using var httpClient = _httpClientFactory.CreateClient();

            if (!string.IsNullOrEmpty(authorization))
                httpClient.DefaultRequestHeaders.Add("Authorization", authorization);

            // 发起 POST 请求
            using var response = await httpClient.PostAsync(apiUrl, content);

            try
            {
                if (response != null && response.Content != null)
                    return JsonConvert.DeserializeObject<ReturnModel>(await response.Content.ReadAsStringAsync());

                return null;
            }
            catch { throw; }
        }

        /// <summary>
        /// get request
        /// </summary>
        /// <param name="apiUrl"></param>
        /// <returns></returns>
        public async Task<ReturnModel> Get(string apiUrl, string authorization = "")
        {
            using var client = _httpClientFactory.CreateClient();

            if (!string.IsNullOrEmpty(authorization))
                client.DefaultRequestHeaders.Add("Authorization", authorization);

            // 发起 Get 请求
            using var response = await client.GetAsync(apiUrl);

            try
            {
                if (response != null && response.Content != null)
                    return JsonConvert.DeserializeObject<ReturnModel>(await response.Content.ReadAsStringAsync());

                return null;
            }
            catch { throw; }
        }

        /// <summary>
        /// 获取新拼接的url地址
        /// </summary>
        /// <param name="url"></param>
        /// <param name="parm"></param>
        /// <returns></returns>
        public string GetNewUrl(string url, params object[] parm)
        {
            StringBuilder urlBuilder = new StringBuilder(url);

            if (url.IndexOf("?") == -1) urlBuilder.Append("?");
            else if (!url.EndsWith("&")) urlBuilder.Append("&");

            if (parm == null || parm.Length <= 0)
                return urlBuilder.ToString().TrimEnd('?').TrimEnd('&');

            if (parm.Length % 2 != 0)
                throw new Exception("parm参数数量不正确");

            for (int i = 0; i < parm.Length / 2; i++)
            {
                var index = i * 2;
                urlBuilder.Append($"{parm[index]}={parm[index + 1]}&");
            }

            return urlBuilder.ToString().TrimEnd('&');
        }
    }
    #endregion
}
